Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PTM Stoichiometry #797

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft

Conversation

pcruzparri
Copy link

@pcruzparri pcruzparri commented Aug 27, 2024

Creating a mzLib method to calculate the stoichiometry (or site-occupancy) of PTMs using the intensity of each quantified peak. The current inputs are the protein database(s) file(.xml) paths and the AllQuantifiedPeaks.tsv file path. The output, occupancyDict, is currently a dictionary of nested dictionaries with the following structure:

{{string PROTEIN1, {{int MAA1, {{string MODNAME1, double INTENSITY}, 
                                {string MODNAME2, double INTENSITY},
                                ...,
                                {string "Total", double INTENSITY}}} 
                    {int MAA2, {...}}, 
                   ...}},
 {string PROTEIN2, {...}},
 ...}

where PROTEINX is the protein accession, MAAX is the modified amino acid at protein position X, and MODNAME1 is the full label of the modification. For each MAAX, there is a "Total" key (instead of a modification name) that holds the total intensity of that amino acid measured in the quantified peaks file, including modified and unmodified peptides with that specific residue.

The general approach is to first get all of the modification intensities and record those in occupancyDict while storing in proteinSeqRangesSeen a dictionary with protein accession keys and values stored as a list of (STARTINDEX, ENDINDEX, INTENSITY) tuples. This helps keep track of the index ranges seen for each protein. Once we have parsed all of the mods, for every amino acid falling into any of those ranges, we increase its "Total" intensity by that amount.

From our discussion, I've added below some of the items I'd like to get some opinions about. Imade them a task list primarily for me to keep track of what I've figured out.

  • Where should this code live in mzLib. The most reasonable suggestions so far are in FlashLFQResults and Readers/QuantificationResults.
  • To interface this nicely with MetaMorpheus, what should the inputs be? My goal now is to look into how/where this will be integrated into MM, but any suggestions on places to look to figure this out are appreciated.
  • I have some ideas on making the code more efficient/succinct, especially foreseeing a lot more information about the peaks being readily available in MM (like the exact protein index for a peptide/peak). Any new ideas are welcomed.

Thanks in advance!


// get the localized modifications from the peptide full sequence and add any amino acid/modification combination not
// seen yet to the occupancy dictionary
foreach (KeyValuePair<int, List<string>> aaWithModList in peptideMods)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In situations like this, you can use "var aaWithModList" instead of specifying the actual class

Copy link
Member

@nbollis nbollis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think readers/Quant... is the best place for it. That way it can be used to find occupancy of the results from another software should that be desired.

In order to optimize your inputs and outputs of the function, you should break your test method into two. One test method with reads in all the data you need. Another method (not a test method) that gets called to calculate the occupancy. This will help you to better understand what is needed for the method, and for use to help make recommendations

@pcruzparri
Copy link
Author

Requesting a second round of reviews! The second to last commit contains a little more in detail most changes. Currently pending work is to create a small enough subset of the raw data to create a test similar to the TestFlashLFQoutputRealData() test. More rigorous testing can be done with some of the identifications in the vignette data, since some base sequences have enough variations in fullSequence mods and positions to have better case coverage.

I'd be happy to hear about 1) code optimization, 2) currently written tests, and 3) clarifications on code commenting. In a conversation, Nic suggested using objects for my main ptm calculation code rather than the 5-level deep dictionary, thoughts on that would be useful as well. Ofc, anything else is useful. TIA!

Copy link

codecov bot commented Oct 11, 2024

Codecov Report

Attention: Patch coverage is 94.35897% with 11 lines in your changes missing coverage. Please review.

Project coverage is 77.85%. Comparing base (e4dda42) to head (8141580).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
mzLib/FlashLFQ/Peptide.cs 0.00% 7 Missing ⚠️
mzLib/MzLibUtil/PositionFrequencyAnalysis.cs 97.18% 2 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #797      +/-   ##
==========================================
+ Coverage   77.78%   77.85%   +0.06%     
==========================================
  Files         230      230              
  Lines       34152    34307     +155     
  Branches     3538     3564      +26     
==========================================
+ Hits        26566    26710     +144     
- Misses       6983     6992       +9     
- Partials      603      605       +2     
Files with missing lines Coverage Δ
mzLib/FlashLFQ/FlashLFQResults.cs 92.04% <ø> (ø)
mzLib/MzLibUtil/ClassExtensions.cs 100.00% <100.00%> (ø)
mzLib/Omics/SpectrumMatch/SpectrumMatchFromTsv.cs 97.05% <100.00%> (-0.29%) ⬇️
mzLib/MzLibUtil/PositionFrequencyAnalysis.cs 97.18% <97.18%> (ø)
mzLib/FlashLFQ/Peptide.cs 92.85% <0.00%> (-7.15%) ⬇️

... and 8 files with indirect coverage changes

{
// use a regex to get all modifications
string pattern = @"\[(.+?)\]";
Regex regex = new(pattern);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to make sure that this method never thinks that
[hydroxylation]EPT[phospho] is accidentaly identified as a mod for P[hydroxylation]EPT[phospho]IDE
I'm not sure that ]EPT[ won't be ignored by your regex

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After finding an opening bracket, regex will always find the next closing bracket, except (updated now) in the case where the closing bracket belongs to an ion charge state.

namespace MzLibUtil
{
// Should this have all of the parent data (i.e. protein group, protein, peptide, peptide position)? Unnecessary for now, but probably useful later.
public class UtilModification
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UtilModification => LocalizedModificationFromTsv
modName => IdWithMotif
position =>PeptidePositionZeroIsNterminus

{
public string FullSequence { get; set; }
public string BaseSequence { get; set; }
public UtilProtein ParentProtein { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should be ProteinGroup?

}
}

public class UtilProtein
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flashlfq proteingroup

@trishorts
Copy link
Contributor

it's possible that "Identification" should be the currency of this realm as it is what is passed into flashlfq by MM and it is what is generated by FlashLFQ when it is run alone on any acceptable input.
image

…ve amino acid positions depending on the length for the modification string and its index. Current approach fixes that.
…sitionFrequencyAnalysis UtilProtein class (now updates peptide mod positions to protein positions) and PFA argument (list of named tuple for clarity)
@pcruzparri
Copy link
Author

Some pending changes:
Potentially modify the input to ProteinGroupsOccupancyByPeptide() be some object and create an interface rather than a list.
Remove occupancy additions to FlashLFQ. These additions have been moved to MetaMorpheus.
Create new package for modification quantification within MzLib.

Side Note:
This branch/pr is a mess. I made a new clean branch on my fork from the master branch and cherry-picked the important, recent commits from this branch. I can change the pull request to track that branch unless there is opposition.

…d of FlashLFQ to output occupancy. Updated UtilClasses for correct UtilProtein.ModifiedAminoAcidPositionsInProtein positions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants